import operator
from typing import Annotated

from langgraph.errors import GraphRecursionError
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict


class State(TypedDict):
    # The operator.add reducer fn makes this append-only
    aggregate: Annotated[list, operator.add]


def node_a(state: State):
    return {"aggregate": ["I'm A"]}


def node_b(state: State):
    return {"aggregate": ["I'm B"]}


def node_c(state: State):
    return {"aggregate": ["I'm C"]}


def node_d(state: State):
    return {"aggregate": ["I'm A"]}


builder = StateGraph(State)
builder.add_node("a", node_a)
builder.add_node("b", node_b)
builder.add_node("c", node_c)
builder.add_node("d", node_d)

builder.add_edge(START, "a")
builder.add_edge("a", "b")
builder.add_edge("a", "c")
builder.add_edge(["b", "c"], "d")
builder.add_edge("d", END)
graph = builder.compile()

try:
    graph.invoke({"aggregate": []}, {"recursion_limit": 4})
except GraphRecursionError:
    print("Recursion Error")